package cn.liuyang.tinyioc.beans.factory;

import cn.liuyang.tinyioc.beans.BeanDefinition;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractBeanFactory implements BeanFactory {

    private Map<String, BeanDefinition> beanDefinitionHashMap = new ConcurrentHashMap<String, BeanDefinition>();
    private final List<String> beanDefinitionNames = new ArrayList<>();

    @Override
    public Object getBean(String name) throws Exception {
        BeanDefinition beanDefinition = beanDefinitionHashMap.get(name);
        if (null == beanDefinition) {
            throw new IllegalArgumentException("no bean named " + name + " is defined");
        }
        Object bean = beanDefinition.getBean();
        if (null == bean) {
            bean = doCreateBean(beanDefinition);
        }
        return bean;
    }

    public void registryBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception {
        // 将注册时初始化bean改为getBean时初始化bean
        beanDefinitionHashMap.put(name, beanDefinition);
        beanDefinitionNames.add(name);

    }

    /**
     * registryBeanDefinition后，再预实例化单例
     *
     * @throws Exception
     */
    public void preInstantiateSingletons() throws Exception {
        for (Iterator<String> it = beanDefinitionNames.iterator(); it.hasNext(); ) {
            String beanDefinitionName = it.next();
            getBean(beanDefinitionName);
        }

    }

    abstract Object doCreateBean(BeanDefinition definition) throws Exception;
}
